// Copyright (C) Recursion Company. All rights reserved.

package vol

import (
	"fmt"
	"io"
	"os"
)

// 火山程序所允许的最大数组维数为6维
func GetAryLen6[E any](ary [][][][][][]E, nDimIndex int) int {
	nLen := len(ary)
	if nDimIndex == 0 {
		return nLen
	}

	if nLen == 0 {
		return 0
	}
	return GetAryLen5(ary[0], nDimIndex-1)
}

func GetAryLen5[E any](ary [][][][][]E, nDimIndex int) int {
	nLen := len(ary)
	if nDimIndex == 0 {
		return nLen
	}

	if nLen == 0 {
		return 0
	}
	return GetAryLen4(ary[0], nDimIndex-1)
}

func GetAryLen4[E any](ary [][][][]E, nDimIndex int) int {
	nLen := len(ary)
	if nDimIndex == 0 {
		return nLen
	}

	if nLen == 0 {
		return 0
	}
	return GetAryLen3(ary[0], nDimIndex-1)
}

func GetAryLen3[E any](ary [][][]E, nDimIndex int) int {
	nLen := len(ary)
	if nDimIndex == 0 {
		return nLen
	}

	if nLen == 0 {
		return 0
	}
	return GetAryLen2(ary[0], nDimIndex-1)
}

func GetAryLen2[E any](ary [][]E, nDimIndex int) int {
	nLen := len(ary)
	if nDimIndex == 0 {
		return nLen
	}

	if nLen == 0 {
		return 0
	}
	return GetAryLen1(ary[0], nDimIndex-1)
}

func GetAryLen1[E any](ary []E, nDimIndex int) int {
	Assert(nDimIndex == 0, "Invalid array dim index")
	return len(ary)
}

func ToAny(val any) any {
	return val
}

func Choose[T any](nIndex int, ary ...T) T {
	if nIndex >= 0 && nIndex < len(ary) {
		return ary[nIndex]
	}
	var val T
	return val
}

func CloneNativeObject[T any](pObject *T) *T {
	var objNew T = *pObject
	return &objNew
}

//-------------------------------------------------------------

func GetObjectString(pObject any) string {
	if iString, ok := pObject.(fmt.Stringer); ok {
		return iString.String()
	}

	return ""
}

func IsFileExist(filePath string) bool {
	_, err := os.Stat(filePath)
	return err == nil
}

func CopyFile(src, dst string, blFailIfDstExist bool) bool {
	for {
		if blFailIfDstExist && IsFileExist(dst) {
			break
		}

		sourceFileStat, err := os.Stat(src)
		if err != nil || !sourceFileStat.Mode().IsRegular() {
			break
		}

		source, err := os.Open(src)
		if err != nil {
			break
		}
		defer source.Close()

		destination, err := os.Create(dst)
		if err != nil {
			break
		}
		defer destination.Close()

		_, err = io.Copy(destination, source)
		return err == nil
	}

	return false
}

//-------------------------------------------------------------

func Fprint(w io.Writer, a ...any) error {
	if w == nil {
		w = os.Stdout
	}
	_, err := fmt.Fprint(w, a...)
	return err
}

func Fprintf(w io.Writer, format string, a ...any) error {
	if w == nil {
		w = os.Stdout
	}
	_, err := fmt.Fprintf(w, format, a...)
	return err
}

func Fprintln(w io.Writer, a ...any) error {
	if w == nil {
		w = os.Stdout
	}
	_, err := fmt.Fprintln(w, a...)
	return err
}

func Fscan(r io.Reader, a ...any) error {
	if r == nil {
		r = os.Stdin
	}
	_, err := fmt.Fscan(r, a...)
	return err
}

func Fscanf(r io.Reader, format string, a ...any) error {
	if r == nil {
		r = os.Stdin
	}
	_, err := fmt.Fscanf(r, format, a...)
	return err
}

func Fscanln(r io.Reader, a ...any) error {
	if r == nil {
		r = os.Stdin
	}
	_, err := fmt.Fscanln(r, a...)
	return err
}

func Print(a ...any) error {
	_, err := fmt.Print(a...)
	return err
}

func Printf(format string, a ...any) error {
	_, err := fmt.Printf(format, a...)
	return err
}

func Println(a ...any) error {
	_, err := fmt.Println(a...)
	return err
}

func Scan(a ...any) error {
	_, err := fmt.Scan(a...)
	return err
}

func Scanf(format string, a ...any) error {
	_, err := fmt.Scanf(format, a...)
	return err
}

func Scanln(a ...any) error {
	_, err := fmt.Scanln(a...)
	return err
}

func Sscan(str string, a ...any) error {
	_, err := fmt.Sscan(str, a...)
	return err
}

func Sscanf(str string, format string, a ...any) error {
	_, err := fmt.Sscanf(str, format, a...)
	return err
}

func Sscanln(str string, a ...any) error {
	_, err := fmt.Sscanln(str, a...)
	return err
}
